package com.avocado.util;



import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @Author: zsh
 * @Date: 2023/10/18 11:56
 */
public class FileUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(FileUtil.class);
    /**
     * 文件是否存在
     * @param path 路径
     * @return 是否存在
     */
    public static boolean fileExist(String path) {
        File file = new File(path);
        return file.exists() && file.isFile();
    }

    /**
     * 文件是否存在
     * @param dir 目录
     * @param fileName 文件名
     * @return 是否存在
     */
    public static boolean fileExist(String dir, String fileName) {
        return fileExist(dir + File.separator + fileName);
    }

    /**
     * 目录是否存在
     * @param path 路径
     * @return 是否存在
     */
    public static boolean dirExist(String path) {
        File file = new File(path);
        return file.exists() && file.isDirectory();
    }

    /**
     * 创建文件
     * @param path 路径
     * @return 是否成功
     */
    public static boolean createFile(String path) {
        try {
            File file = new File(path);
            file.createNewFile();
            return true;
        } catch (IOException e) {
            return false;
        }
    }

    /**
     * 创建文件
     * @param dir 目录
     * @param fileName 文件名
     * @return 是否成功
     */
    public static boolean createFile(String dir, String fileName) {
        return createFile(dir + File.separator + fileName);
    }

    /**
     * 删除文件
     * @param path 路径
     * @return 是否成功
     */
    public static boolean deleteFile(String path) {
        File file = new File(path);
        return file.delete();
    }

    /**
     * 删除文件
     * @param dir 目录
     * @param fileName 文件名
     * @return 是否成功
     */
    public static boolean deleteFile(String dir, String fileName) {
        return deleteFile(dir + File.separator + fileName);
    }

    private static List<String> getFiles(String dir, Pattern pattern, boolean recursive) {
        File target = new File(dir);
        String[] files = target.list();
        if (files == null || files.length < 1) {
            return null;
        }

        List<String> result = new ArrayList<>();
        String childFileName = null;
        File childFile = null;
        for (String fileName : files) {
            if (pattern != null && !pattern.matcher(fileName).matches()) {
                continue;
            }
            childFileName = dir + File.separator + fileName;
            childFile = new File(childFileName);
            if (childFile.isFile()) {
                result.add(childFileName);
            } else if(recursive && childFile.isDirectory()) {
                List<String> childResult = getFiles(childFileName, pattern, recursive);
                if (childResult != null) {
                    result.addAll(childResult);
                }
            }
        }
        return result;
    }

    /**
     * 获取目录下文件列表
     * @param dir 目录名
     * @param pattern 正则表达式
     * @param recursive 是否递归
     * @return 文件列表
     * @throws IOException io异常
     */
    public static List<String> listFiles(String dir, Pattern pattern, boolean recursive) throws IOException {
        if (!dirExist(dir)) {
            throw new IOException(dir + " is not exist!");
        }
        return _listFiles(dir, pattern, recursive);
    }

    /**
     * 获取目录下文件列表
     * @param packageName 包名
     * @param dir 目录名
     * @param pattern 正则表达式
     * @param recursive 是否递归
     * @return 文件列表
     * @throws IOException io异常
     */
    public static List<String> listFiles(String packageName, String dir, Pattern pattern, boolean recursive) throws IOException {
        if (!dirExist(dir)) {
            throw new IOException(dir + " is not exist!");
        }
        return _listFiles(packageName, dir, pattern, recursive);
    }

    /**
     * 读取文件内容
     * @param path 文件绝对路径
     * @return 返回内容
     */
    public static String readFileContent(String path) throws IOException {
        File file = new File(path);
        if (!file.exists() || !file.isFile()) {
            return null;
        }
        return new String(Files.readAllBytes(Paths.get(file.toURI())), "utf-8");
    }

    /**
     * 读取文件内容
     * @param path  文件所在目录
     * @param fileName 文件名
     * @return 读取的内容
     * @throws IOException
     */
    public static String readFileContent(String path, String fileName) throws IOException {
        return readFileContent(path + '/' + fileName);
    }

    private static List<String> _listFiles(String dirPath, Pattern pattern, boolean recursive) {
        File thisDir = new File(dirPath);
        String[] files = thisDir.list();
        if (files == null || files.length < 1) {
            return null;
        }
        List<String> result = new ArrayList<>();
        String childFileName = null;
        File childFile = null;
        for (String fileName : files) {
            childFileName = dirPath + '/' + fileName;
            childFile = new File(childFileName);
            if (childFile.isFile()) {
                if (pattern != null && !pattern.matcher(fileName).matches()) {
                    continue;
                }
                result.add(childFileName);
            } else if (recursive && childFile.isDirectory()) {
                List<String> childResult = _listFiles(childFileName, pattern, recursive);
                if (childResult != null) {
                    result.addAll(childResult);
                }
            }
        }
        return result;
    }

    private static List<String> _listFiles(String packageName, String dirPath, Pattern pattern, boolean recursive) {
        File thisDir = new File(dirPath);
        String[] files = thisDir.list();
        if (files == null || files.length < 1) {
            return null;
        }
        List<String> result = new ArrayList<>();
        String childFileName = null;
        File childFile = null;
        for (String fileName : files) {
            childFileName = dirPath + '/' + fileName;
            childFile = new File(childFileName);
            if (childFile.isFile()) {
                if (pattern != null && !pattern.matcher(fileName).matches()) {
                    continue;
                }
                result.add(packageName + '.' + fileName);
            } else if (recursive && childFile.isDirectory()) {
                List<String> childResult = _listFiles(packageName + '.' + fileName, childFileName, pattern, recursive);
                if (childResult != null) {
                    result.addAll(childResult);
                }
            }
        }
        return result;
    }

    public static String readFileAsString(String path) {
        File file = new File(path);
        FileInputStream is = null;
        BufferedReader reader = null;
        StringBuilder stringBuilder = null;
        try {
            if (file.length() != 0) {
                is = new FileInputStream(file);
                InputStreamReader streamReader = new InputStreamReader(is);
                reader = new BufferedReader(streamReader);
                String line;
                stringBuilder = new StringBuilder();
                while ((line = reader.readLine()) != null) {
                    stringBuilder.append(line);
                    stringBuilder.append("\n");
                }
                stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length());
                reader.close();
            }
        } catch (Exception e) {
            LOGGER.error("", e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    LOGGER.error("", e);
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    LOGGER.error("", e);
                }
            }
        }
        return String.valueOf(stringBuilder);
    }
}
